package com.seezoon.infrastructure.configuration.interceptor;

import com.seezoon.infrastructure.configuration.context.SecurityContextHolder;
import com.seezoon.infrastructure.dto.Response;
import com.seezoon.infrastructure.error.ErrorCode;
import com.seezoon.infrastructure.tcp.session.Session;
import com.seezoon.infrastructure.tcp.session.SessionManager;
import com.seezoon.infrastructure.utils.JsonUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.HandlerInterceptor;

public class SessionInterceptor implements HandlerInterceptor {

    private static final String PREFIX = "Bearer ";
    private static int PREFIX_LENGTH = PREFIX.length();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
        if (StringUtils.isEmpty(authorization) || !authorization.startsWith(PREFIX)
                || authorization.length() <= PREFIX_LENGTH) {
            // 401 未登录
            return false;
        }
        String token = authorization.substring(PREFIX_LENGTH);
        if (StringUtils.isEmpty(token)) {
            // 401 未登录
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return false;
        }
        Session session = SessionManager.getInstance().get(token);
        if (session == null) {
            this.output(response, ErrorCode.DEVICE_NOT_ONLINE.code(), ErrorCode.DEVICE_NOT_ONLINE.msg());
            return false;
        }
        SecurityContextHolder.setSession(session);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        SecurityContextHolder.clear();
    }

    private void output(HttpServletResponse response, int code, String msg) throws IOException {
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        String json = JsonUtils.toJson(Response.error(code, msg));
        try (PrintWriter writer = response.getWriter()) {
            writer.write(json);
            writer.flush();
        }
    }

}
